package com.thf.util;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JdbcUtil {
    static final String URL ="jdbc:mysql://localhost:3306/huarui?useUnicode=true&characterEncoding=utf8";
    static final String USERNAME ="root";
    static final String PASSWORD ="100626";
    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    static Connection getConnection(){
        Connection con =null ;
        try {
            con =DriverManager.getConnection(URL,USERNAME,PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return con ;
    }
    static void close(Connection con , PreparedStatement pstmt){
        try {
            if(pstmt!=null){
                pstmt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(con!=null){
                con.close();
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    static void  close(Connection con, PreparedStatement pstmt, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (pstmt != null) {
                pstmt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (con != null) {
                con.close();
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public static <T> List<T> executeQuery(String sql ,Class<T> clz,Object...params){
        List<T> list = new ArrayList<>();
        Connection con = getConnection();
        PreparedStatement pstmt = null ;
        ResultSet rs =null ;
        try {
            pstmt= con.prepareStatement(sql);
            if(pstmt!=null){
                for(int i=0;i<params.length;i++){
                    pstmt.setObject(i+1,params[i]);
                }
            }
            rs = pstmt.executeQuery();
            try {
                while(rs.next()) {
                    T t = clz.newInstance();
                    Field[] fields = clz.getDeclaredFields();
                    for (Field field : fields) {

                        Object object = rs.getObject(field.isAnnotationPresent(Column.class) ? field.getAnnotation(Column.class).value() : field.getName());
                        //Object object = rs.getObject(field.getName());
                        field.setAccessible(true);
                        field.set(t, object);
                    }
                    list.add(t);
                }
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(con,pstmt,rs);
        }
        return list;
    }

    public static <T> T queryOne(String sql ,Class<T> clz,Object...params){
        T t =null ;
        Connection con = getConnection();
        PreparedStatement pstmt = null ;
        ResultSet rs =null ;
        try {
            pstmt= con.prepareStatement(sql);
            if(pstmt!=null){
                for(int i=0;i<params.length;i++){
                    pstmt.setObject(i+1,params[i]);
                }
            }
            rs = pstmt.executeQuery();
            try {
                if (rs.next()) {
                    t = clz.newInstance();
                    Field[] fields = clz.getDeclaredFields();
                    int i = 0 ;
                    for (Field field : fields) {
                        Object object = rs.getObject(field.isAnnotationPresent(Column.class) ? field.getAnnotation(Column.class).value() : field.getName());
                        //Object object = rs.getObject(field.getName());
                        field.setAccessible(true);
                        field.set(t, object);
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(con,pstmt,rs);
        }
        return t;
    }

    public static int count(String sql,Object...params){
        Connection con = getConnection();
        PreparedStatement  pstmt = null;
        ResultSet rs = null;
        int result = 0 ;
        try {
            try {
                pstmt = con.prepareStatement(sql);
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            if(pstmt!=null){
                for(int i =0;i<params.length;i++){
                    pstmt.setObject(i+1,params[i]);
                }
                rs =pstmt.executeQuery();
                if (rs.next()){
                    result = rs.getInt(1);
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(con,pstmt,rs);
        }
        return result;
    }

     public static int executeUpdate(String sql,Object...params){
         PreparedStatement pstmt =null;
         int result =0 ;
         Connection con =getConnection();
         try {
             pstmt = con.prepareStatement(sql);
             if(pstmt!=null){

                 for(int i =0; i<params.length;i++){
                     pstmt.setObject(i+1,params[i]);
                 }
                 result =pstmt.executeUpdate();
             }

         } catch (SQLException e) {
             e.printStackTrace();
         }finally {
             close(con,pstmt);
         }
         return  result;
     }
}
